package dao

import (
	"context"
	"errors"

	"bmember/pkg/util"

	"bmember/pkg/db/pgex"

	"bmember/internal/model"
)

// MemberAddressDao  收货账号
type MemberAddressDao interface {
	// CreateAddress 创建地址
	CreateAddress(ctx context.Context, addr *model.MemberAddress) (int64, error)
	// UpdateAddressById 更新地址
	UpdateAddressById(ctx context.Context, addr *model.MemberAddress) error
	// GetAddressById 根据id获取地址
	GetAddressById(ctx context.Context, id int64) (*model.MemberAddress, error)
	// GetAddressesByMember 根据memberId 加载地址列表
	GetAddressesByMember(ctx context.Context, memberId int64) ([]*model.MemberAddress, error)
	// DelAddressById 删除地址
	DelAddressById(ctx context.Context, addr *model.MemberAddress) error
}

type addrDaoImpl struct {
	*DaoBase
	name string
}

var addrDao MemberAddressDao

// InitMemberAddressDao 初始化 member account
func InitMemberAddressDao() {
	addrDao = &addrDaoImpl{
		DaoBase: daoBase,
		name:    "dao_member_address",
	}
}

// GetMemberAddressDao 获取 member account dao
func GetMemberAddressDao() MemberAddressDao {
	return addrDao
}

// CreateAddress 创建地址
func (dao *addrDaoImpl) CreateAddress(ctx context.Context, addr *model.MemberAddress) (int64, error) {
	if addr == nil {
		return 0, nil
	}
	param := []interface{}{
		addr.BrandId,
		addr.MemberId,
		addr.ContactName,
		addr.ContactMobile,
		addr.Gender,
		addr.Title,
		addr.Address,
		addr.StreetNo,
		addr.CityCode,
		addr.Tag,
		addr.Latitude,
		addr.Longitude,
	}
	query := "INSERT INTO member_address (brand_id, member_id, contact_name, contact_mobile, gender, title, address, " +
		"street_no, city_code, tag, latitude, longitude, created_at, updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,NOW(),NOW())"
	aff, err := dao.db.PgExec(ctx, "id", query, param...)
	if err != nil {
		return 0, err
	}
	lastId, _ := aff.GetLastId()
	return lastId, nil
}

// UpdateAddressById 更新地址
func (dao *addrDaoImpl) UpdateAddressById(ctx context.Context, addr *model.MemberAddress) error {
	if addr == nil {
		return nil
	}
	param := []interface{}{
		addr.ContactName,
		addr.ContactMobile,
		addr.Gender,
		addr.Title,
		addr.Address,
		addr.StreetNo,
		addr.CityCode,
		addr.Tag,
		addr.Latitude,
		addr.Longitude,
		addr.Id,
	}
	query := "UPDATE member_address SET  contact_name=?, contact_mobile=?, gender=?, title=?, address=?, " +
		"street_no=?, city_code=?, tag=?, latitude=?, longitude=?, updated_at=NOW() WHERE id=? AND deleted_at=0"
	_, err := dao.db.Update(ctx, query, param...)
	return err
}

// GetAddressById 根据id获取地址
func (dao *addrDaoImpl) GetAddressById(ctx context.Context, id int64) (*model.MemberAddress, error) {
	addr := &model.MemberAddress{}
	query := "SELECT * FROM member_address WHERE id=? AND deleted_at=0"
	err := dao.db.Get(ctx, addr, query, id)
	if err != nil && errors.Is(err, pgex.ErrEmpty) {
		return nil, nil
	}
	return addr, err
}

// GetAddressesByMember 根据memberId 加载地址
func (dao *addrDaoImpl) GetAddressesByMember(ctx context.Context, memberId int64) ([]*model.MemberAddress, error) {
	var addrs []*model.MemberAddress
	query := "SELECT id, member_id, contact_name, contact_mobile, gender, title, address, street_no, city_code, " +
		"tag, latitude, longitude  FROM member_address WHERE member_id=? AND deleted_at=0"
	err := dao.db.Query(ctx, &addrs, query, memberId)
	return addrs, err
}

// DelAddressById 删除地址
func (dao *addrDaoImpl) DelAddressById(ctx context.Context, addr *model.MemberAddress) error {
	if addr == nil {
		return nil
	}
	if addr.DeletedAt == 0 {
		addr.DeletedAt = util.GetCurrentTimestamp()
	}
	query := "UPDATE member_address SET deleted_at=? WHERE id=? AND deleted_at=0"
	_, err := dao.db.Update(ctx, query, addr.DeletedAt, addr.Id)
	return err
}
